package com.wang.avi.indicators;

import com.wang.avi.AVLoadingIndicatorView;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.ArrayList;

/**
 * Created by Jack on 2015/10/18.
 */
public class CubeTransitionIndicator extends AVLoadingIndicatorView {

    float[] translateX=new float[2],translateY=new float[2];
    float degrees,scaleFloat=1.0f;

    public CubeTransitionIndicator(Context context) {
        super(context);
        Component.DrawTask task = (component, canvas) -> {
            setPaint();
            setBound();
            draw(canvas,getPaint());
        };
        addDrawTask(task);
    }

    @Override
    public void addDrawTask(Component.DrawTask drawTask){
        super.addDrawTask(drawTask);
        drawTask.onDraw(this, mCanvasForTaskOverContent);
    }

    @Override
    public void draw(Canvas canvas, Paint paint) {
        float rWidth=getWidth()/5;
        float rHeight=getHeight()/5;
        for (int i = 0; i < 2; i++) {
            canvas.save();
            canvas.translate(translateX[i], translateY[i]);
            canvas.rotate(degrees,0,0);
            canvas.scale(scaleFloat,scaleFloat);
            RectFloat rectF=new RectFloat(-rWidth/2,-rHeight/2,rWidth/2,rHeight/2);
            canvas.drawRect(rectF,paint);
            canvas.restore();
        }
    }

    @Override
    public ArrayList<AnimatorValue> onCreateAnimators() {
        ArrayList<AnimatorValue> animators=new ArrayList<>();
        float startX=getWidth()/5;
        float startY=getHeight()/5;
        for (int i = 0; i < 2; i++) {
            final int index=i;
            translateX[index]=startX;
            AnimatorValue translationXAnim=new AnimatorValue();
            translationXAnim.setCurveType(Animator.CurveType.LINEAR);
            translationXAnim.setDuration(1600);
            translationXAnim.setLoopedCount(-1);
            translationXAnim.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                @Override
                public void onUpdate(AnimatorValue animatorValue, float v) {
                    if (index ==1)
                        translateX[index] =  translationXHs(getWidth()-startX,startX,v);
                    else
                        translateX[index] =  translationXHs(startX,getWidth()-startX,v);
                    invalidate();
                }
            });
            translateY[index]=startY;
            AnimatorValue translationYAnim=new AnimatorValue();
            translationYAnim.setDuration(1600);
            translationYAnim.setCurveType(Animator.CurveType.LINEAR);
            translationYAnim.setLoopedCount(-1);
            addUpdateListener(translationYAnim,new AnimatorValue.ValueUpdateListener() {
                @Override
                public void onUpdate(AnimatorValue animatorValue, float v) {
                    if (index ==0)
                        translateY[index] =  translationYHs(startY,getHeight()-startY,v);
                    else
                        translateY[index] =  translationYHs(getHeight()-startY,startY,v);
                    invalidate();
                }
            });
            animators.add(translationXAnim);
            animators.add(translationYAnim);
        }

        AnimatorValue scaleAnim=new AnimatorValue();
        scaleAnim.setDuration(1600);
        scaleAnim.setCurveType(Animator.CurveType.LINEAR);
        scaleAnim.setLoopedCount(-1);
        addUpdateListener(scaleAnim,new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                scaleFloat = scaleHs(v);
                invalidate();
            }
        });

        AnimatorValue rotateAnim=new AnimatorValue();
        rotateAnim.setDuration(1600);
        rotateAnim.setCurveType(Animator.CurveType.LINEAR);
        rotateAnim.setLoopedCount(-1);
        addUpdateListener(rotateAnim,new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                degrees = v*720;
                invalidate();
            }
        });

        animators.add(scaleAnim);
        animators.add(rotateAnim);
        return animators;
    }

    protected float translationXHs(float a,float b,float v){
        float res=0;
        if (v<= (float) 1/4)
            res=4*(b-a)*v+a;
        else if (v> (float) 1/4 && v<= (float) 1/2)
            res=b;
        else if (v> (float) 1/2 && v<= (float) 3/4)
            res=4*(a-b)*v+(3*b-2*a);
        else
            res=a;
        return res;
    }
    protected float translationYHs(float a,float b,float v){
        float res=0;
        if (v<= (float) 1/4)
            res=a;
        else if (v> (float) 1/4 && v<= (float) 1/2)
            res=v*4*(b-a)+(2*a-b);
        else if (v> (float) 1/2 && v<= (float) 3/4)
            res=b;
        else
            res=v*4*(a-b)+4*b-3*a;
        return res;
    }

    protected float scaleHs(float v){
        float res=0;
        if (v<= (float) 1/4)
            res=-2*v+1;
        else if (v> (float) 1/4 && v<= (float) 1/2)
            res=v*2;
        else if (v> (float) 1/2 && v<= (float) 3/4)
            res=-2*v+2;
        else
            res=v*2-1;
        return res;
    }

}
